﻿using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar.SuperGrid;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;

namespace PlanningGIS.Statistics
{
    public class AreaCreator
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="grid">测区列表</param>
        public AreaCreator(SuperGridControl grid)
        {
            _SuperGrid = grid;
            InitControl();
        }
        /// <summary>
        /// 列表对象
        /// </summary>
        private SuperGridControl _SuperGrid = null;

        /// <summary>
        /// 绘制到地图中的对象
        /// </summary>
        public List<IElement> DrawElements { get; private set; }

        /// <summary>
        /// 获取列表中所有的选中测区
        /// </summary>
        public List<IFeature> _CheckedFeatures { get; protected set; }

        /// <summary>
        /// 标识测区名称的字段名
        /// </summary>
        public string m_nameField = "OBJECTID";

        /// <summary>
        /// 
        /// </summary>
        private string _Name = "_AreaCreator";

        /// <summary>
        /// 地图关联对象
        /// </summary>
        private IHookHelper _HookHelper = null;

        /// <summary>
        /// 地图关联对象
        /// </summary>
        public object Hook
        {
            set
            {
                try
                {
                    _HookHelper = new HookHelper();
                    _HookHelper.Hook = value;
                }
                catch
                {
                    _HookHelper = null;
                }
            }
        }

        /// <summary>
        /// 初始化控件
        /// </summary>
        private void InitControl()
        {
            GridColumn chk = new GridColumn();
            chk.EditorType = typeof(GridCheckBoxXEditControl);
            chk.HeaderText = "";
            chk.Name = "colCheck";
            chk.Width = 40;
            _SuperGrid.PrimaryGrid.Columns.Add(chk);
            GridColumn chk1 = new GridColumn();
            chk1.EditorType = typeof(GridTextBoxXEditControl);
            chk1.HeaderText = "OID";
            chk1.Name = "colName";
            chk1.Width = 300;
            chk1.ReadOnly = false;
            _SuperGrid.PrimaryGrid.Columns.Add(chk1);
            _SuperGrid.PrimaryGrid.UseAlternateRowStyle = true;
            _SuperGrid.PrimaryGrid.ShowRowGridIndex = true;
            _SuperGrid.PrimaryGrid.SelectionGranularity = SelectionGranularity.Row;
            GridCheckBoxXEditControl colCheck = _SuperGrid.PrimaryGrid.Columns[0].EditControl as GridCheckBoxXEditControl;
            colCheck.CheckedChangedEx += colCheck_CheckedChangedEx;
            GridTextBoxXEditControl colName = _SuperGrid.PrimaryGrid.Columns["colName"].EditControl as GridTextBoxXEditControl;
            _CheckedFeatures = new List<IFeature>();
        }


        /// <summary>
        /// 获取选择的要素
        /// </summary>
        public IFeature SeletedFeature
        {
            get
            {
                if (_SuperGrid.PrimaryGrid.Rows.Count == 0) return null;
                if (_SuperGrid.PrimaryGrid.SelectedRowCount == 0) return null;
                if (_SuperGrid.PrimaryGrid.ActiveRow == null) return null;
                GridRow r = (GridRow)(_SuperGrid.PrimaryGrid.ActiveRow);
                IFeature st = (IFeature)r.Tag;
                return st;
            }
        }

        /// <summary>
        /// 获取列表中所有选中的要素
        /// </summary>
        public List<IFeature> CheckedFeatures
        {
            get
            {
                if (_CheckedFeatures == null || _CheckedFeatures.Count == 0) return null;
                return _CheckedFeatures;
            }
        }

        /// <summary>
        /// 选择状态改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void colCheck_CheckedChangedEx(object sender, CheckBoxXChangeEventArgs e)
        {
            if (e.EventSource == DevComponents.DotNetBar.eEventSource.Code) return;
            GridCheckBoxXEditControl ctl = sender as GridCheckBoxXEditControl;
            GridRow r = ((IGridCellEditControl)ctl).EditorCell.GridRow;
            IFeature feature = (IFeature)r.Tag;
            if (ctl.Checked)
            {
                if (_CheckedFeatures.Find(t => t.OID == feature.OID) != null) return;
                _CheckedFeatures.Add(feature);
                AddToMap(feature.Shape, feature.OID.ToString());
            }
            else
            {
                if (_CheckedFeatures.Find(t => t.OID == feature.OID) == null) return;
                _CheckedFeatures.RemoveAll(t => t.OID == feature.OID);
                RemoveToMap(feature.OID.ToString());
            }
        }


        /// <summary>
        /// 获取所选择的测区对应的空间对象（合并为一个空间对象）
        /// </summary>
        /// <returns></returns>
        public IGeometry GetSelectGeometry()
        {
            if (_CheckedFeatures == null || _CheckedFeatures.Count == 0) return null;
            var v = from p in _CheckedFeatures
                    select p.Shape;
            return GeometryHelper.Union((List<IGeometry>)v.ToList());
        }

        /// <summary>
        /// 添加测区
        /// </summary>
        /// <param name="pFeatCls"></param>
        public void AddArea(IFeatureClass pFeatCls)
        {
            try
            {
                _SuperGrid.PrimaryGrid.Rows.Clear();
                if (_CheckedFeatures.Count > 0) _CheckedFeatures.Clear();
                _CheckedFeatures = new List<IFeature>();
                Clear();
                IFeatureCursor pFeatCur = pFeatCls.Search(null, false);
                IFeature pFeat = null;
                string name;
                while ((pFeat = pFeatCur.NextFeature()) != null)
                {
                    if (pFeat.Shape == null || pFeat.Shape.IsEmpty) continue;
                    name = pFeat.OID.ToString();
                    GridRow r = new GridRow(new object[] { true, name });
                    _SuperGrid.PrimaryGrid.Rows.Add(r);
                    //r.AllowEdit = true;
                    r.Cells["colCheck"].AllowEdit = true;
                    r.Cells["colName"].AllowEdit = false;
                    r.Tag = pFeat;
                    _CheckedFeatures.Add(pFeat);
                    AddToMap(pFeat.Shape, pFeat.OID.ToString());
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.Message);
            }
        }

        /// <summary>
        /// 将选中的对象添加的地图中
        /// </summary>
        /// <param name="geometry"></param>
        /// <param name="code"></param>
        private void AddToMap(IGeometry geometry, string id)
        {
            if (_HookHelper == null) return;
            if (geometry == null || geometry.IsEmpty) return;
            if (DrawElements == null) DrawElements = new List<IElement>();
            if (DrawElements.Count > 0)
            {
                int cnt = DrawElements.Count(t => (t as IElementProperties3).Name.Equals(id));
                if (cnt > 0) return;
            }
            IRgbColor rgbColor = new RgbColor();
            rgbColor.Red = 255;
            rgbColor.Green = 0;
            rgbColor.Blue = 0;
            IElement ele = ElementHelper.AddPolygon(geometry as IPolygon, _HookHelper.ActiveView, rgbColor);
            (ele as IElementProperties3).Name = _Name + id;
            DrawElements.Add(ele);
        }

        /// <summary>
        /// 将指定的对象从地图中移除
        /// </summary>
        /// <param name="code"></param>
        private void RemoveToMap(string id)
        {
            if (_HookHelper == null) return;
            if (DrawElements == null) DrawElements = new List<IElement>();
            if (DrawElements.Count == 0) return;
            IElement ele = DrawElements.FirstOrDefault(t => (t as IElementProperties3).Name.Equals(_Name + id));
            if (ele == null || ele.Geometry == null) return;
            RemoveElement(ele);
            DrawElements.Remove(ele);
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGeography, null, _HookHelper.ActiveView.Extent);
        }
        /// <summary>
        /// 清除地图上绘制的对象
        /// </summary>
        public void Clear()
        {
            if (_HookHelper == null) return;
            if (DrawElements == null || DrawElements.Count == 0) return;

            IGraphicsContainer grp = _HookHelper.ActiveView.GraphicsContainer;
            grp.Reset();
            IElement ele = null;
            while ((ele = grp.Next()) != null)
            {
                IElementProperties ep = ele as IElementProperties;
                if (string.IsNullOrWhiteSpace(ep.Name)) continue;
                if (ep.Name.StartsWith(_Name)) grp.DeleteElement(ele);
            }
            DrawElements.Clear();
            DrawElements = new List<IElement>();
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGraphicSelection, null, _HookHelper.ActiveView.Extent);

            //foreach (IElement itm in DrawElements)
            //{
            //    RemoveElement(itm);
            //}
            //DrawElements.Clear();
            //DrawElements = new List<IElement>();
            //_HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGeography, null, _HookHelper.ActiveView.Extent);
        }

        /// <summary>
        /// 移除指定的对象
        /// </summary>
        /// <param name="ele"></param>
        private void RemoveElement(IElement ele)
        {
            try
            {
                IEnumElement em = _HookHelper.ActiveView.GraphicsContainer.LocateElementsByEnvelope(ele.Geometry.Envelope);
                if (em.Next() != null)
                    _HookHelper.ActiveView.GraphicsContainer.DeleteElement(ele);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 单击行闪烁图形
        /// </summary>
        public void FlashSelected()
        {
            DisplayHelper.FlashGeometry(((IFeature)_SuperGrid.PrimaryGrid.ActiveRow.Tag).Shape, _HookHelper.Hook as IMapControl3);
        }

        /// <summary>
        /// 双击行缩放到图形
        /// </summary>
        public void ZoomToSelected()
        {
            IGeometry pGeomElement = ((IFeature)_SuperGrid.PrimaryGrid.ActiveRow.Tag).Shape as IGeometry;
            ISpatialReference pSR = pGeomElement.SpatialReference;

            if (_HookHelper.FocusMap.SpatialReference != null && !_HookHelper.FocusMap.SpatialReference.Equals(pGeomElement.SpatialReference))
            {
                pGeomElement.Project(_HookHelper.FocusMap.SpatialReference);
            }
            IElement pElement = ElementHelper.GetEleFromGeom(pGeomElement);
            //pGeomElement.Project(pSR);
            double ex = 10.0;
            IUnitConverter pUnitConverter = new UnitConverter();
            IGeographicCoordinateSystem pGCS = _HookHelper.FocusMap.SpatialReference as IGeographicCoordinateSystem;
            if (_HookHelper.FocusMap.SpatialReference is IGeographicCoordinateSystem)//地图为投影坐标系
                ex = pUnitConverter.ConvertUnits(ex, esriUnits.esriMeters, esriUnits.esriDecimalDegrees);
            IEnvelope pEnvelope = pElement.Geometry.Envelope;
            pEnvelope.Expand(ex, ex, false);
            _HookHelper.ActiveView.Extent = pEnvelope;
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGeography, null, _HookHelper.ActiveView.Extent);
            _HookHelper.ActiveView.ScreenDisplay.UpdateWindow();
        }

        /// <summary>
        /// 选择控制
        /// </summary>
        /// <param name="type"></param>
        public void Select(selType type)
        {
            switch (type)
            {
                case selType.All:
                    foreach (GridRow r in _SuperGrid.PrimaryGrid.Rows)
                    {
                        if ((bool)r.Cells["colCheck"].Value == false)
                        {
                            r.Cells["colCheck"].Value = true;
                            IFeature feature = (IFeature)r.Tag;
                            if (_CheckedFeatures.Find(t => t.OID == feature.OID) != null) continue;
                            _CheckedFeatures.Add(feature);
                            AddToMap(feature.Shape, feature.OID.ToString());
                        }
                    }
                    break;
                case selType.NONE:
                    foreach (GridRow r in _SuperGrid.PrimaryGrid.Rows)
                    {
                        if ((bool)r.Cells["colCheck"].Value == true)
                        {
                            r.Cells["colCheck"].Value = false;
                            IFeature feature = (IFeature)r.Tag;
                            if (_CheckedFeatures.Find(t => t.OID == feature.OID) == null) continue;
                            _CheckedFeatures.RemoveAll(t => t.OID == feature.OID);
                            RemoveToMap(feature.OID.ToString());
                        }
                    }
                    break;
                case selType.REVERSE:
                    foreach (GridRow r in _SuperGrid.PrimaryGrid.Rows)
                    {
                        if ((bool)r.Cells["colCheck"].Value == true)
                        {
                            r.Cells["colCheck"].Value = false;
                            IFeature feature = (IFeature)r.Tag;
                            if (_CheckedFeatures.Find(t => t.OID == feature.OID) == null) continue;
                            _CheckedFeatures.RemoveAll(t => t.OID == feature.OID);
                            RemoveToMap(feature.OID.ToString());
                        }

                        else
                        {
                            r.Cells["colCheck"].Value = true;
                            IFeature feature = (IFeature)r.Tag;
                            if (_CheckedFeatures.Find(t => t.OID == feature.OID) != null) continue;
                            _CheckedFeatures.Add(feature);
                            AddToMap(feature.Shape, feature.OID.ToString());
                        }
                    }
                    break;
                default:
                    return;
            }
        }
    }

    /// <summary>
    /// 选择类型
    /// </summary>
    public enum selType
    {
        /// <summary>
        /// 全选
        /// </summary>
        All,
        /// <summary>
        /// 全不选
        /// </summary>
        NONE,
        /// <summary>
        /// 反选
        /// </summary>
        REVERSE,
    }
}
